home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CreatingGames / Utilities / C / Mesa / samples / overlay.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-20  |  8.1 KB  |  382 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <math.h>
  29. #include <time.h>
  30. #include "GL/gl.h"
  31. #include "GL/glu.h"
  32. #include "gltk.h"
  33.  
  34.  
  35. #ifndef PI
  36. #define PI 3.141592657
  37. #endif
  38.  
  39.  
  40. enum {
  41.     NORMAL = 0,
  42.     WEIRD = 1
  43. };
  44.  
  45. enum {
  46.     STREAK = 0,
  47.     CIRCLE = 1
  48. };
  49.  
  50. #define MAXSTARS 400
  51. #define MAXPOS 10000
  52. #define MAXWARP 10
  53. #define MAXANGLES 6000
  54.  
  55.  
  56. typedef struct _starRec {
  57.     GLint type;
  58.     float x[2], y[2], z[2];
  59.     float offsetX, offsetY, offsetR, rotation;
  60. } starRec;
  61.  
  62.  
  63. GLenum doubleBuffer, directRender;
  64. GLint windW, windH;
  65.  
  66. GLenum flag = NORMAL, overlayInit = GL_FALSE;
  67. GLint starCount = MAXSTARS / 2;
  68. float speed = 1.0;
  69. GLint nitro = 0;
  70. starRec stars[MAXSTARS];
  71. float sinTable[MAXANGLES];
  72.  
  73.  
  74. float Sin(float angle)
  75. {
  76.  
  77.     return (sinTable[(GLint)angle]);
  78. }
  79.  
  80. float Cos(float angle)
  81. {
  82.  
  83.     return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
  84. }
  85.  
  86. void NewStar(GLint n, GLint d)
  87. {
  88.  
  89.     if (rand()%4 == 0) {
  90.     stars[n].type = CIRCLE;
  91.     } else {
  92.     stars[n].type = STREAK;
  93.     }
  94.     stars[n].x[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
  95.     stars[n].y[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
  96.     stars[n].z[0] = (float)(rand() % MAXPOS + d);
  97.     if (rand()%4 == 0 && flag == WEIRD) {
  98.     stars[n].offsetX = (float)(rand() % 100 - 100 / 2);
  99.     stars[n].offsetY = (float)(rand() % 100 - 100 / 2);
  100.     stars[n].offsetR = (float)(rand() % 25 - 25 / 2);
  101.     } else {
  102.     stars[n].offsetX = 0.0;
  103.     stars[n].offsetY = 0.0;
  104.     stars[n].offsetR = 0.0;
  105.     }
  106. }
  107.  
  108. void RotatePoint(float *x, float *y, float rotation)
  109. {
  110.     float tmpX, tmpY;
  111.  
  112.     tmpX = *x * Cos(rotation) - *y * Sin(rotation);
  113.     tmpY = *y * Cos(rotation) + *x * Sin(rotation);
  114.     *x = tmpX;
  115.     *y = tmpY;
  116. }
  117.  
  118. void MoveStars(void)
  119. {
  120.     float offset;
  121.     GLint n;
  122.  
  123.     offset = speed * 60.0;
  124.  
  125.     for (n = 0; n < starCount; n++) {
  126.     stars[n].x[1] = stars[n].x[0];
  127.     stars[n].y[1] = stars[n].y[0];
  128.     stars[n].z[1] = stars[n].z[0];
  129.     stars[n].x[0] += stars[n].offsetX;
  130.     stars[n].y[0] += stars[n].offsetY;
  131.     stars[n].z[0] -= offset;
  132.         stars[n].rotation += stars[n].offsetR;
  133.         if (stars[n].rotation > MAXANGLES) {
  134.             stars[n].rotation = 0.0;
  135.     }
  136.     }
  137. }
  138.  
  139. GLenum StarPoint(GLint n)
  140. {
  141.     float x0, y0, x1, y1, width;
  142.     GLint i;
  143.  
  144.     x0 = stars[n].x[0] * windW / stars[n].z[0];
  145.     y0 = stars[n].y[0] * windH / stars[n].z[0];
  146.     RotatePoint(&x0, &y0, stars[n].rotation);
  147.     x0 += windW / 2.0;
  148.     y0 += windH / 2.0;
  149.  
  150.     if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) {
  151.     if (stars[n].type == STREAK) {
  152.         x1 = stars[n].x[1] * windW / stars[n].z[1];
  153.         y1 = stars[n].y[1] * windH / stars[n].z[1];
  154.         RotatePoint(&x1, &y1, stars[n].rotation);
  155.         x1 += windW / 2.0;
  156.         y1 += windH / 2.0;
  157.  
  158.         glLineWidth(MAXPOS/100.0/stars[n].z[0]+1.0);
  159.         glColor3f(1.0, (MAXWARP-speed)/MAXWARP, (MAXWARP-speed)/MAXWARP);
  160.         if (fabs(x0-x1) < 1.0 && fabs(y0-y1) < 1.0) {
  161.         glBegin(GL_POINTS);
  162.             glVertex2f(x0, y0);
  163.         glEnd();
  164.         } else {
  165.         glBegin(GL_LINES);
  166.             glVertex2f(x0, y0);
  167.             glVertex2f(x1, y1);
  168.         glEnd();
  169.         }
  170.     } else {
  171.         width = MAXPOS / 10.0 / stars[n].z[0] + 1.0;
  172.         glColor3f(1.0, 0.0, 0.0);
  173.         glBegin(GL_POLYGON);
  174.         for (i = 0; i < 8; i++) {
  175.             float x = x0 + width * Cos((float)i*MAXANGLES/8.0);
  176.             float y = y0 + width * Sin((float)i*MAXANGLES/8.0);
  177.             glVertex2f(x, y);
  178.         };
  179.         glEnd();
  180.     }
  181.     return GL_TRUE;
  182.     } else {
  183.     return GL_FALSE;
  184.     }
  185. }
  186.  
  187. void ShowStars(void)
  188. {
  189.     GLint n;
  190.  
  191.     glClear(GL_COLOR_BUFFER_BIT);
  192.  
  193.     for (n = 0; n < starCount; n++) {
  194.     if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) {
  195.         if (StarPoint(n) == GL_FALSE) {
  196.         NewStar(n, MAXPOS);
  197.         }
  198.     } else {
  199.         NewStar(n, MAXPOS);
  200.     }
  201.     }
  202. }
  203.  
  204. static void Init(void)
  205. {
  206.     float angle;
  207.     GLint n;
  208.  
  209.     srand((unsigned int)time(NULL));
  210.  
  211.     for (n = 0; n < MAXSTARS; n++) {
  212.     NewStar(n, 100);
  213.     }
  214.  
  215.     angle = 0.0;
  216.     for (n = 0; n < MAXANGLES ; n++) {
  217.     sinTable[n] = sin(angle);
  218.         angle += PI / (MAXANGLES / 2.0);
  219.     }
  220.  
  221.     glClearColor(0.0, 0.0, 0.0, 0.0);
  222.  
  223.     glDisable(GL_DITHER);
  224. }
  225.  
  226. void Reshape(int width, int height)
  227. {
  228.  
  229.     windW = (GLint)width;
  230.     windH = (GLint)height;
  231.  
  232.     if (tkSetWindowLevel(TK_OVERLAY) == GL_TRUE) {
  233.     glViewport(0, 0, windW, windH);
  234.     glMatrixMode(GL_PROJECTION);
  235.     glLoadIdentity();
  236.     gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
  237.     glMatrixMode(GL_MODELVIEW);
  238.     overlayInit = GL_FALSE;
  239.     }
  240.  
  241.     if (tkSetWindowLevel(TK_RGB) == GL_TRUE) {
  242.     glViewport(0, 0, windW, windH);
  243.     glMatrixMode(GL_PROJECTION);
  244.     glLoadIdentity();
  245.     gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
  246.     glMatrixMode(GL_MODELVIEW);
  247.     }
  248. }
  249.  
  250. static GLenum Key(int key, GLenum mask)
  251. {
  252.  
  253.     switch (key) {
  254.       case TK_ESCAPE:
  255.     tkQuit();
  256.       case TK_SPACE:
  257.     flag = (flag == NORMAL) ? WEIRD : NORMAL;
  258.     break;
  259.       case TK_t:
  260.     nitro = 1;
  261.     break;
  262.       default:
  263.     return GL_FALSE;
  264.     }
  265.     return GL_TRUE;
  266. }
  267.  
  268. void Idle(void)
  269. {
  270.  
  271.     if (overlayInit == GL_FALSE) {
  272.     if (tkSetWindowLevel(TK_OVERLAY) == GL_TRUE) {
  273.         glClear(GL_COLOR_BUFFER_BIT);
  274. /*        glColor3f(1.0, 0.0, 0.0);*/
  275.  
  276.             glIndexf( 2.0 );
  277.         glBegin(GL_POLYGON);
  278.         glVertex2i(windW/4-10, windH/4-10);
  279.         glVertex2i(windW/2-10, windH/4-10);
  280.         glVertex2i(windW/2-10, windH/2-10);
  281.         glVertex2i(windW/4-10, windH/2-10);
  282.         glEnd();
  283.  
  284.             glIndexf( 0.0 );
  285.         glBegin(GL_POLYGON);
  286.         glVertex2i(windW/4, windH/4);
  287.         glVertex2i(windW/2, windH/4);
  288.         glVertex2i(windW/2, windH/2);
  289.         glVertex2i(windW/4, windH/2);
  290.         glEnd();
  291.  
  292.             glIndexf( 1.0 );
  293.         glBegin(GL_POLYGON);
  294.         glVertex2i(windW/4+10, windH/4+10);
  295.         glVertex2i(windW/2+10, windH/4+10);
  296.         glVertex2i(windW/2+10, windH/2+10);
  297.         glVertex2i(windW/4+10, windH/2+10);
  298.         glEnd();
  299.  
  300.  
  301.         if (tkSetWindowLevel(TK_RGB) == GL_FALSE) {
  302.         printf("Can't switch to main window!\n");
  303.         }
  304.     }
  305.     overlayInit = GL_TRUE;
  306.     }
  307.  
  308.     MoveStars();
  309.     ShowStars();
  310.     if (nitro > 0) {
  311.     speed = (float)(nitro / 10) + 1.0;
  312.     if (speed > MAXWARP) {
  313.         speed = MAXWARP;
  314.     }
  315.     if (++nitro > MAXWARP*10) {
  316.         nitro = -nitro;
  317.     }
  318.     } else if (nitro < 0) {
  319.     nitro++;
  320.     speed = (float)(-nitro / 10) + 1.0;
  321.     if (speed > MAXWARP) {
  322.         speed = MAXWARP;
  323.     }
  324.     }
  325.  
  326.     glFlush();
  327.     if (doubleBuffer) {
  328.     tkSwapBuffers();
  329.     }
  330. }
  331.  
  332. static GLenum Args(int argc, char **argv)
  333. {
  334.     GLint i;
  335.  
  336.     doubleBuffer = GL_FALSE;
  337.     directRender = GL_TRUE;
  338.  
  339.     for (i = 1; i < argc; i++) {
  340.     if (strcmp(argv[i], "-sb") == 0) {
  341.         doubleBuffer = GL_FALSE;
  342.     } else if (strcmp(argv[i], "-db") == 0) {
  343.         doubleBuffer = GL_TRUE;
  344.     } else if (strcmp(argv[i], "-dr") == 0) {
  345.         directRender = GL_TRUE;
  346.     } else if (strcmp(argv[i], "-ir") == 0) {
  347.         directRender = GL_FALSE;
  348.     }
  349.     }
  350.     return GL_TRUE;
  351. }
  352.  
  353. void main(int argc, char **argv)
  354. {
  355.     GLenum type;
  356.  
  357.     if (Args(argc, argv) == GL_FALSE) {
  358.     tkQuit();
  359.     }
  360.  
  361.     windW = 300;
  362.     windH = 300;
  363.     tkInitPosition(0, 0, 300, 300);
  364.  
  365.     type = TK_OVERLAY | TK_RGB;
  366.     type |= (doubleBuffer) ? TK_DOUBLE : TK_SINGLE;
  367.     type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  368.     tkInitDisplayMode(type);
  369.  
  370.     if (tkInitWindow("Overlay Test") == GL_FALSE) {
  371.     tkQuit();
  372.     }
  373.  
  374.     Init();
  375.  
  376.     tkExposeFunc(Reshape);
  377.     tkReshapeFunc(Reshape);
  378.     tkKeyDownFunc(Key);
  379.     tkIdleFunc(Idle);
  380.     tkExec();
  381. }
  382.